﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.IO;
using Microsoft.Xna.Framework;

using Warlock.GameStuff.Network;
using Warlock.GameStuff;

namespace Warlock
{
    class Netcom
    {
        public class Server
        {
            static string dnserver;
            static string dnsmap;
            static bool gameexit = false;
            
            public Server(String DNS, String Map)
            {
                dnserver = DNS;
                dnsmap = Map;
                StremTCP(7536);
            }
            public Server()
            {
                StremTCP(7536);
            }


            static TcpListener TCP2;
            static Socket TCP3;


            public static void StremTCP(int PORT)
            {
                TcpListener TCPl = null;
                System.Threading.Thread worki;

                worki = new System.Threading.Thread(new System.Threading.ThreadStart(controlconect));
                try
                {
                    IPEndPoint ep = new IPEndPoint(IPAddress.Any, PORT);
                    TCPl = new TcpListener(ep);
                    TCPl.Start();
                    TCP2 = TCPl;
                    worki.Start();
                    if (dnserver != null)
                    {
                        Socket eins = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        eins.Connect(Dns.GetHostEntry(dnserver).AddressList[0], 7536);
                        Send(eins, "newGame:" + dnsmap, WarlockProt.Packettype.DNSGAME);
                        eins.Close();
                    }
                }
                catch (SocketException err)
                {
                    Console.WriteLine("ERROR: " + err);
                    Console.ReadLine();
                }

            }

            public static void socketace()
            {
                Recive(TCP3);
            }

            public static void controlconect()
            {
                while (true)
                {

                    if (TCP2.Pending())
                    {
                        System.Threading.Thread worker = new System.Threading.Thread(new System.Threading.ThreadStart(socketace));
                        TCP3 = TCP2.AcceptSocket();
                        worker.Start();
                    }
                    System.Threading.Thread.Sleep(100);
                }

            }

            static SortedList<int, Playerinfo> Gamer = new SortedList<int, Playerinfo>();
            static List<Int32> IDs = new List<int>();
            static int id = 0;
            static int Players = 0;

            public static void Recive(Socket TCP1)
            {
                int Playerid = 0;
                String[] SplitPlayerinfo = new String[10];
                int Playerlistid = 0;
                while (true)
                {
                    try
                    {
                        Warlock.GameStuff.Network.WarlockProt.Packettype Type;
                        string newData = Warlock.GameStuff.Network.WarlockProt.analyse(TCP1,out Type);
                        
                        if (newData.Length != 0)
                        {
                                switch (Type)
                                {
                                    case (WarlockProt.Packettype.newPlayer):
                                        {
                                            Gamer.Add(id, new Playerinfo(newData, id));
                                            IDs.Add(id);
                                            Send(TCP1, id.ToString(), WarlockProt.Packettype.ID);
                                            /*for (int i = 0; i <= Gamer.Count; i++)
                                            {
                                                Send(TCP1, Gamer[i].ToString(), WarlockProt.Packettype.Playerlist);
                                            }*/
                                            foreach (int i in IDs)
                                            {
                                                Send(TCP1, Gamer[i].ToString(), WarlockProt.Packettype.Playerlist);
                                            }
                                            Console.WriteLine("newPlayer: " + newData);
                                            Playerid = id;
                                            id++;
                                            Players++;
                                        }
                                        break;
                                    case (WarlockProt.Packettype.PlayerlistUpdate):
                                        {
                                            foreach (int i in IDs)
                                            {
                                                Send(TCP1, Gamer[i].ToString(), WarlockProt.Packettype.PlayerlistUpdate);
                                            }
                                        }
                                        break;
                                    case (WarlockProt.Packettype.PlayerUpdate):
                                        {
                                            if (Gamer.Count != 0)
                                            {
                                                String[] spliter = newData.Split(new char[] { ';' });
                                                if (spliter[0].Length < 3)
                                                {
                                                    Gamer[Convert.ToInt32(spliter[0])].PlayerinfoUpadate(newData);
                                                }
                                            }
                                        }
                                        break;
                                }                            
                        }
                    }
                    catch (Exception se)
                    {
                        Console.WriteLine(se.Message);
                        Gamer.Remove(Playerid);
                        Players--;
                        TCP1.Close();
                        break;
                    }
                    finally
                    {
                    }
                }
            }

            public static void Send(Socket TCP1, String text,WarlockProt.Packettype Type)
            {
                //byte[] byteBuffer = System.Text.Encoding.ASCII.GetBytes(text);
                //TCP1.Send(byteBuffer, 0, byteBuffer.Length, SocketFlags.None);
                byte[] byte1;
                byte[] byte2;
                byte[] byte3;
                Warlock.GameStuff.Network.WarlockProt.Packetbuilder(text, Type,out byte1,out byte2, out byte3);
                TCP1.Send(byte1, 0, byte1.Length, SocketFlags.None);
                TCP1.Send(byte2, 0, byte2.Length, SocketFlags.None);
                TCP1.Send(byte3, 0, byte3.Length, SocketFlags.None);
            }


        }
        public class Client
        {
            public static Socket TCP1;
            public static SortedList<int, Playerinfo> Gamer = new SortedList<int, Playerinfo>();
            public static List<int> Playerids = new List<int>();
            public static int persid = -1;
            public Client(String IP, int PORT)
            {
                Stream(IP, PORT);
            }
            public static void socketace()
            {
                Recive(TCP1);
            }

            public static void Stream(String IP, int PORT)
            {
                try
                {
                    TCP1 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    Gamer.Capacity = 20;
                    TCP1.Connect(IPAddress.Parse(IP),7536);
                    //TCP1.SendTimeout = TimeSpan.FromMilliseconds(100).Milliseconds;
                    //TCP1.Blocking = false;
                    System.Threading.Thread worker = new System.Threading.Thread(new System.Threading.ThreadStart(socketace));
                    worker.Start();
                    
                }
                catch (SocketException err)
                {
                    Console.WriteLine("ERROR: " + err);
                    Console.ReadLine();
                }
            }
            public static void Recive(Socket TCP1)
            {

                while (true)
                {

                    try
                    {
                        Warlock.GameStuff.Network.WarlockProt.Packettype Type;
                        string newData = Warlock.GameStuff.Network.WarlockProt.analyse(TCP1, out Type);
                        if(newData.Length != 0)
                        {
                            switch (Type)
                            {
                                case WarlockProt.Packettype.ID:
                                    {
                                        persid = Convert.ToInt32(newData);
                                    }
                                    break;
                                case WarlockProt.Packettype.Playerlist:
                                    {
                                        String[] spliter = newData.Split(new char[] { ';' });
                                        Gamer.Add(Convert.ToInt32(spliter[0]), new Playerinfo(newData.Remove( 0, spliter[0].Length +1), Convert.ToInt32(spliter[0])));
                                        Playerids.Add(Convert.ToInt32(spliter[0]));
                                    }
                                    break;
                                case WarlockProt.Packettype.PlayerlistUpdate:
                                    {
                                        String[] spliter = newData.Split(new char[] { ';' });
                                        if (Gamer.ContainsKey(Convert.ToInt32(spliter[0])))
                                        {
                                            Gamer[Convert.ToInt32(spliter[0])].PlayerinfoUpadate(newData);
                                        }
                                        else
                                        {
                                            Playerids.Add(Convert.ToInt32(spliter[0]));
                                            Gamer.Add(Convert.ToInt32(spliter[0]), new Playerinfo(newData.Remove(0, spliter[0].Length + 1), Convert.ToInt32(spliter[0])));
                                        }
                                    }
                                    break;
                            }
                        }
                        }
                    catch (SocketException se)
                    {
                        Console.WriteLine(se.Message);
                        TCP1.Close();
                        break;
                    }
                    finally
                    {
                        //Console.WriteLine(games);
                    }
                    //System.Threading.Thread.Sleep(100);
                }
            }
            public static class sender
            {
                static Socket TCPSocked;
                static String sendtext;
                static WarlockProt.Packettype PType;

                public static void Send(Socket TCP1, String text, WarlockProt.Packettype Type)
                {
                    //byte[] byteBuffer = System.Text.Encoding.ASCII.GetBytes(text);
                    //TCP1.Send(byteBuffer, 0, byteBuffer.Length, SocketFlags.None);
                    TCPSocked = TCP1;
                    sendtext = text;
                    PType = Type;
                    //System.Threading.Thread worker = new System.Threading.Thread(new System.Threading.ThreadStart(Sendthred));
                    //worker.Start();
                    try
                    {
                        int bytes = 0;
                        byte[] byte1;
                        byte[] byte2;
                        byte[] byte3;
                        Warlock.GameStuff.Network.WarlockProt.Packetbuilder(sendtext, PType, out byte1, out byte2, out byte3);
                        int bytes1 = TCPSocked.Send(byte1,0,byte1.Length, SocketFlags.Partial);
                        int bytes2 = TCPSocked.Send(byte2, 0, byte2.Length, SocketFlags.Partial);
                        int bytes3 = TCPSocked.Send(byte3, 0, byte3.Length, SocketFlags.Partial);

                    }
                    catch(SocketException e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }
                /*public static void Sendthred()
                {
                    byte[] byte1;
                    byte[] byte2;
                    byte[] byte3;
                    Warlock.GameStuff.Network.WarlockProt.Packetbuilder(sendtext, PType, out byte1, out byte2, out byte3);
                    TCPSocked.Send(byte1, 0, byte1.Length, SocketFlags.None);
                    TCPSocked.Send(byte2, 0, byte2.Length, SocketFlags.None);
                    TCPSocked.Send(byte3, 0, byte3.Length, SocketFlags.None);
                }*/
            }
        }
    }
}
